﻿#region Imports
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Reflection;
using DataAnnotationsContrib.Finance;
using DataAnnotationsContrib.Interfaces;
using DataAnnotationsContrib.Tests.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endregion

namespace DataAnnotationsContrib.Tests.Finance
{
    /// <summary>
    /// </summary>
    [TestClass]
    public class Iso13616IBANAlgorithmTest : ValidationAlgorithmTest<Iso13616IBANAlgorithm>
    {
        #region Data
        private static readonly List<string> __validValues = new List<string>();
        private static readonly List<string> __inValidValues = new List<string>();
        private static readonly List<string> __countryCodes = new List<string>();
        private static readonly List<string> __bbans = new List<string>();
        private static readonly List<string> __bankIds = new List<string>();
        private static readonly List<string> __branchIds = new List<string>();
        #endregion

        static Iso13616IBANAlgorithmTest()
        {
            var thisAssembly = typeof(Iso13616IBANAlgorithmTest).Assembly;

            var stream = thisAssembly.GetManifestResourceStream("DataAnnotationsContrib.Tests.Resources.Iso13616IBANAlgorithmValidTestData.csv");
            using (var reader = new StreamReader(stream))
            {
                bool firstLine = true;
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (!firstLine && !line.StartsWith("--"))
                    {
                        string[] parts = line.Split(';');
                        __validValues.Add(parts[1]);
                        __countryCodes.Add(parts[0]);
                        __bbans.Add(parts[3]);
                        __bankIds.Add(parts.Length >= 5 ? parts[4] : "");
                        __branchIds.Add(parts.Length >= 6 ? parts[5] : "");
                    }
                    firstLine = false;
                }
            }

            stream = thisAssembly.GetManifestResourceStream("DataAnnotationsContrib.Tests.Resources.Iso13616IBANAlgorithmInvalidTestData.csv");
            using (var reader = new StreamReader(stream))
            {
                bool firstLine = true;
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (!firstLine && !line.StartsWith("--"))
                    {
                        string[] parts = line.Split(';');
                        __inValidValues.Add(parts[1]);
                    }
                    firstLine = false;
                }
            }
        }

        public Iso13616IBANAlgorithmTest()
            : base(__validValues, __inValidValues)
        { }

        #region Tests
        [TestMethod]
        public void AllValidValuesShouldValidateTrue()
        {
            TestAllValidValuesShouldValidateTrue();
        }
        [TestMethod]
        public void AllInvalidValuesShouldValidateFalse()
        {
            TestAllInvalidValuesShouldValidateFalse();
        }

        [TestMethod]
        public void ShouldExtractCountryCode()
        {
            for (int i = 0; i < __validValues.Count; i++)
            {
                Assert.AreEqual(__countryCodes[i], Iso13616IBANAlgorithm.ExtractCountryCode(__validValues[i]), __countryCodes[i]);
            }
        }
        [TestMethod]
        public void ShouldExtractBBAN()
        {
            for (int i = 0; i < __validValues.Count; i++)
            {
                Assert.AreEqual(__bbans[i], Iso13616IBANAlgorithm.ExtractFullBasicBankAccountNumber(__validValues[i]), __countryCodes[i]);
            }
        }
        [TestMethod]
        public void ShouldExtractBankId()
        {
            for (int i = 0; i < __validValues.Count; i++)
            {
                Assert.AreEqual(__bankIds[i], Iso13616IBANAlgorithm.ExtractBankIdentifier(__validValues[i]), __countryCodes[i]);
            }
        }
        [TestMethod]
        public void ShouldExtractBranchId()
        {
            for (int i = 0; i < __validValues.Count; i++)
            {
                Assert.AreEqual(__branchIds[i], Iso13616IBANAlgorithm.ExtractBranchIdentifier(__validValues[i]), __countryCodes[i]);
            }
        }
        [TestMethod]
        public void ShouldExtractAccount()
        {
            for (int i = 0; i < __validValues.Count; i++)
            {
                Assert.IsTrue(__validValues[i].IndexOf(Iso13616IBANAlgorithm.ExtractAccountIdentifier(__validValues[i])) > -1, __countryCodes[i]);
            }
        }

        [TestMethod]
        public void LogFormat()
        {
            LogAllFormatStructureInfo(Iso13616IBANAlgorithm.Formats, f => String.Format("{0} ({1})", f.CountryCode, f.CountryName));
        }
        #endregion
    }
}
